package org.example.utils;

import org.example.enums.ResponseCodeEnum;
import org.example.exception.BizException;
import org.example.model.APIResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author: wf
 * @create: 2020/10/23 13:00
 * @description: 接口请求-模版方法
 */
public abstract class ApiTemplate<T> {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 接口调用失败告警后缀
     */
    private static String INVOKE_FAIL_SUFFIX = "%s_INVOKE_FAIL";
    
    /**
     * 接口调用成功告警后缀
     */
    private static String INVOKE_SUCCESS_SUFFIX = "%s_INVOKE_SUCCESS";
    
    
    /**
     * 监控key
     */
    private String monitorKey;
    
    public ApiTemplate(String monitorKey) {
        this.monitorKey = monitorKey;
    }

    /**
     * 参数校验
     * @throws BizException
     */
    protected abstract void checkParams() throws BizException;

    /**
     * 业务逻辑
     * @return
     * @throws BizException
     */
    protected abstract APIResponse<T> process() throws BizException;

    /**
     * 用于释放资源
     */
    private void afterProcess() {
    }

    /**
     * TODO 异常时需要添加异常监控
     * 执行方法
     * @return
     */
    public APIResponse<T> execute(){
        long start = System.currentTimeMillis();
        APIResponse<T> result = null;
        try {
            this.checkParams();
            result = this.process(); 
            return result;
        } catch (IllegalArgumentException e) {
            logger.error("{} 接口参数解析异常! error msg:{}", String.format(INVOKE_FAIL_SUFFIX, monitorKey), e.getMessage(), e);
            return APIResponse.error(ResponseCodeEnum.PARAM_ERROR, e.getMessage());
        }catch (NullPointerException e){
            logger.error("{} 接口参数解析异常! error msg:{}", String.format(INVOKE_FAIL_SUFFIX, monitorKey), e.getMessage(), e);
            return APIResponse.error(ResponseCodeEnum.PARAM_ERROR, e.getMessage());
        }catch (BizException e){
            logger.error("{} 接口执行出现异常! error msg:{}", String.format(INVOKE_FAIL_SUFFIX, monitorKey), e.getMessage(), e);
            return APIResponse.error(e.getCode(), e.getMsg());
        } catch (Exception e){
            logger.error("{} 接口执行出现异常!, error msg:{}", String.format(INVOKE_FAIL_SUFFIX, monitorKey), e.getMessage(), e);
            return APIResponse.error(ResponseCodeEnum.UNKNOWN_ERROR, ResponseCodeEnum.UNKNOWN_ERROR.getMessage());
        } finally {
            try {
                afterProcess();
            } catch (Exception e) {
                logger.error("execute afterProcess fail", e);
            }
            logger.info("{} 接口执行耗时: {} ms", String.format(INVOKE_SUCCESS_SUFFIX, monitorKey), System.currentTimeMillis() - start);
        }
    }
}